// 定义一个包名为helper.base的包
package helper.base

// 导入相关的类和扩展函数
import helper.base.LHMHelper.A2LHMExpand.add
import helper.base.LHMHelper.A2LHMExpand.makeA2LHM
import helper.base.PrintHelper.toPrettyString
import helper.base.TupleHelper.A2TupleExpand.swap

// 定义一个对象FunArgHelperKt，包含扩展函数和一个内部类
object FunArgHelperKt {
    // 扩展List<A2Tuple<K, V>>类型，添加一个转换为A2LHM（LinkedHashMap的一个抽象表示）的方法
    private fun <K, V> List<A2Tuple<K, V>>.toLHM(): A2LHM<K, V> {
        // 使用makeA2LHM函数创建一个空的A2LHM实例
        val lhm = makeA2LHM<K, V>()
        // 遍历当前List中的所有元素（A2Tuple），并添加到lhm中
        this.forEach { (key, value) ->
            // 确保lhm中还未包含即将添加的key
            require(!lhm.containsKey(key))
            // 使用add方法将键值对添加到lhm中
            lhm.add(key, value)
        }
        // 返回填充好的lhm
        return lhm
    }

    // 定义一个开放的泛型类FunArgHelper
    open class FunArgHelper<E> {
        // 初始化一个空的List<A2Tuple<String, E>>
        open val list = listOf<A2Tuple<String, E>>()

        // 通过懒加载定义一个从String到E的A2LHM映射
        private val aStringELHM: A2LHM<String, E> by lazy {
            // 使用上面定义的toLHM扩展函数转换list为A2LHM
            list.toLHM()
        }

        // 通过懒加载定义一个从E到String的A2LHM映射
        private val aEStringLHM: A2LHM<E, String> by lazy {
            // 先将list中的元素使用swap扩展函数交换键值位置，然后转换为A2LHM
            list.map {
                it.swap()
            }.toLHM()
        }

        // 定义一个函数，通过String类型的key从aStringELHM中获取对应的E类型的值
        fun getValueFromStringELHM(key: String): E {
            // 确保aStringELHM包含给定的key
            require(aStringELHM.containsKey(key))
            // 返回对应的值，非空断言确保返回值不为null
            return aStringELHM[key]!!
        }

        // 定义一个函数，通过E类型的key从aEStringLHM中获取对应的String类型的值
        fun getValueFromEStringLHM(key: E): String {
            // 确保aEStringLHM包含给定的key
            require(aEStringLHM.containsKey(key))
            // 返回对应的值，非空断言确保返回值不为null
            return aEStringLHM[key]!!
        }

        // 打印出aStringELHM和aEStringLHM中的映射
        fun printMappings() {
            println("aStringELHM: ${aStringELHM.toPrettyString()}")
            println("aEStringLHM: ${aEStringLHM.toPrettyString()}")
        }
    }
}
